package com.aplink.generic.xmlparser;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.text.TextUtils;

import com.aplink.generic.GenericFragment;
import com.aplink.generic.constant.ColumnSettingConstant;
import com.aplink.generic.constant.MenuConstant;
import com.aplink.generic.constant.type.ActionType;
import com.aplink.generic.pojo.ColumnSetting;
import com.aplink.generic.pojo.controlspec.ValueList;
import com.aplink.generic.pojo.controlspec.menu.MenuItemSpec;
import com.aplink.generic.pojo.controlspec.menu.PopupMenuSpec;
import com.aplink.generic.util.objectrule.TargetCollection;

public class ColumnSettingParser {

	public static ArrayList<ColumnSetting> parse(
	        final GenericFragment genericFragment, final int xmlFileId) {
		final ColumnSettingParser columnSettingParser = new ColumnSettingParser();
		return columnSettingParser.parserIntoColumnSetting(xmlFileId,
		        ColumnSettingConstant.COLUMN);
	}

	private String getTextNodeValue(final Node node) {
		Node child;
		if (node != null) {
			if (node.hasChildNodes()) {
				child = node.getFirstChild();
				while (child != null) {
					if (child.getNodeType() == Node.TEXT_NODE) {
						return child.getNodeValue();
					}
					child = child.getNextSibling();
				}
			}
		}
		return "";
	}

	private PopupMenuSpec parsePopupMenuFormat(Node nodeFormat) {
		Element elementFormat = (Element) nodeFormat;
		if (elementFormat.hasChildNodes()) {
			final PopupMenuSpec popupMenuFormat = new PopupMenuSpec();
			NodeList nodeListFormat = elementFormat
			        .getElementsByTagName(MenuConstant.POPUP_MENU);
			if (nodeListFormat.getLength() == 0) {
				return null;
			}
			nodeFormat = nodeListFormat.item(0);
			if (nodeFormat.hasAttributes()) {
				final String controlId = XmlPaserUtil.getAttrValue(nodeFormat,
				        MenuConstant.ID);
				popupMenuFormat.setControlId(controlId);
			}
			if (nodeFormat.getNodeType() == Node.ELEMENT_NODE) {
				elementFormat = (Element) nodeFormat;
				nodeListFormat = elementFormat
				        .getElementsByTagName(MenuConstant.SUB_MENU);
				for (int i = 0; i < nodeListFormat.getLength(); i++) {
					final Node nodeItem = nodeListFormat.item(i);
					final MenuItemSpec popupMenuItem = MenuItemParser
					        .parseMenuItemSpec(nodeItem);
					popupMenuFormat.add(popupMenuItem);
				}
			}
			return popupMenuFormat;
		}
		return null;
	}

	private ArrayList<ColumnSetting> parserIntoColumnSetting(
	        final int xmlFileName, final String tagname) {
		try {
			final Document document = XmlPaserUtil
			        .openDocumentFrom(xmlFileName);
			return parseXML(document, tagname);
		} catch (final ParserConfigurationException e) {
			e.printStackTrace();
		} catch (final SAXException e) {
			e.printStackTrace();
		} catch (final IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	private ValueList parseValueList(Node nodeFormat) {
		Element elementFormat = (Element) nodeFormat;
		final ValueList valueList = new ValueList();
		if (elementFormat.hasChildNodes()) {
			NodeList nodeListFormat = elementFormat
			        .getElementsByTagName(ColumnSettingConstant.VALUE_LIST);

			if (nodeListFormat.getLength() > 0) {
				nodeFormat = nodeListFormat.item(0);
				if (nodeFormat.hasAttributes()) {
					final String defaultValue = XmlPaserUtil
					        .getAttrValue(nodeFormat,
					                ColumnSettingConstant.DEFAULT_VALUE_KEY);
					if (!TextUtils.isEmpty(defaultValue)) {
						valueList.setDefaultValue(defaultValue);
					}
				}

				if (nodeFormat.getNodeType() == Node.ELEMENT_NODE) {
					elementFormat = (Element) nodeFormat;
					nodeListFormat = elementFormat
					        .getElementsByTagName(ColumnSettingConstant.VALUE);
					for (int i = 0; i < nodeListFormat.getLength(); i++) {
						final Node nodeItem = nodeListFormat.item(i);
						String display = null;
						if (nodeItem.hasAttributes()) {
							display = XmlPaserUtil.getAttrValue(nodeItem,
							        ColumnSettingConstant.DISPLAY);
						}
						final String nodeValue = XmlPaserUtil
						        .getNodeValue(nodeItem);
						if ((!TextUtils.isEmpty(display))
						        && (!TextUtils.isEmpty(nodeValue))) {
							valueList.put(nodeValue, display);
						}
					}
				}
			}
		}
		return valueList;
	}

	private ArrayList<ColumnSetting> parseXML(final Document doc,
	        final String tagname) {
		final ArrayList<ColumnSetting> columnSettingList = new ArrayList<ColumnSetting>();
		final NodeList nList = doc.getElementsByTagName(tagname);
		for (int temp = 0; temp < nList.getLength(); temp++) {
			final Node nNode = nList.item(temp);
			final ColumnSetting columnsetting = new ColumnSetting();
			// set column type
			if (nNode.hasAttributes()) {
				final String colType = XmlPaserUtil.getAttrValue(nNode,
				        ColumnSettingConstant.TYPE);
				if (colType != null) {
					columnsetting.setColType(colType);
				}

				final String colFormat = XmlPaserUtil.getAttrValue(nNode,
				        ColumnSettingConstant.FORMAT);
				if (colFormat != null) {
					columnsetting.setFormat(colFormat);
				}

				final String dataobj = XmlPaserUtil.getAttrValue(nNode,
				        ColumnSettingConstant.DATA_OBJ);
				if (dataobj != null) {
					columnsetting.setDataObj(dataobj);
				}
			}
			if (nNode.getNodeType() == Node.ELEMENT_NODE) {
				final Element element = (Element) nNode;

				// set mapping name
				NodeList nodes = element
				        .getElementsByTagName(ColumnSettingConstant.MAPPINGNAME);
				if (nodes.getLength() != 0) {
					final Node node = nodes.item(0);
					if (node.hasAttributes()) {
						final String isStaticReource = XmlPaserUtil
						        .getAttrValue(node,
						                ColumnSettingConstant.STATIC_RESOURCE);
						if (isStaticReource.equalsIgnoreCase("Y")) {
							columnsetting.setStaicResource(true);
						}
					} else {
						columnsetting.setMappingName(getTextNodeValue(node));
					}
				}

				// set linking mapping name
				nodes = element
				        .getElementsByTagName(ColumnSettingConstant.LINKINGMAPPINGNAME);
				if (nodes.getLength() != 0) {
					columnsetting.setLinkMappingName(getTextNodeValue(nodes
					        .item(0)));
				}

				// set linkpage
				nodes = element
				        .getElementsByTagName(ColumnSettingConstant.LINKPAGE);
				if (nodes.getLength() != 0) {
					columnsetting.setLinkPage(getTextNodeValue(nodes.item(0)));
				}

				// set header
				nodes = element
				        .getElementsByTagName(ColumnSettingConstant.HEADER);
				if (nodes.getLength() != 0) {
					columnsetting
					        .setHeaderText(getTextNodeValue(nodes.item(0)));
				}

				final PopupMenuSpec popupMenuSpec = parsePopupMenuFormat(nNode);
				if (popupMenuSpec != null) {
					popupMenuSpec.setActiveControl(columnsetting
					        .getLinkMappingName());
					columnsetting.setPopupMenuSpec(popupMenuSpec);
				}

				final ValueList valueList = parseValueList(nNode);
				if (valueList != null) {
					columnsetting.setValueList(valueList);
				}

				// set header
				nodes = element
				        .getElementsByTagName(ColumnSettingConstant.BUTTON);
				if (nodes.getLength() != 0) {
					String value;
					if (nodes.item(0).hasAttributes()) {
						value = XmlPaserUtil.getAttrValue(nodes.item(0),
						        "action");
						columnsetting.setActionType(ActionType.get(value));
					}
					final TargetCollection targetCollection = TargetCollectionPaser
					        .parse(nodes.item(0));
					columnsetting.setTargetCollection(targetCollection);
				}

			}
			columnSettingList.add(columnsetting);
		}
		return columnSettingList;
	}
}
